package com.app.babygo.dbservice;

import java.util.ArrayList;

import com.app.babygo.exceptions.InternalDBException;
import com.app.babygo.exceptions.ObjectNotFoundException;
import com.app.babygo.obj.Child;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;

public class ChildAdapter extends DBAdapter {
	
	// table info of the childinfo
	protected static final String CHILD_ID = "id";
	protected static final String CHILD_PARENT_ID = "parentid";
	protected static final String CHILD_NAME = "name";
	protected static final String CHILD_AGE = "age";
	protected static final String CHILD_GENDER = "gender";
	protected static final String CHILD_INFO = "info";
	protected static final String CHILD_PIC_PATH = "pic_path";
	protected static String TAG = "ChildAdapter";

	
	
	// table creation strings
	protected static final String DATABASE_CREATE_TABLE_CHILDINFO = "create table "
			+ DATABASE_TABLE_CHILD + " ("
			+ CHILD_ID + " text primary key not null, "
			+ CHILD_PARENT_ID + " text not null, "
			+ CHILD_NAME + " text not null, " 
			+ CHILD_AGE + " integer not null, "
			+ CHILD_GENDER + " integer not null, " 
			+ CHILD_INFO + " text not null,"
			+ CHILD_PIC_PATH + " text not null);";


	public ChildAdapter(Context context) {
		super(context);
	}

	/**
	 * Child Info section
	 */
	
	public static boolean createTable(SQLiteDatabase db){
		try {
			db.execSQL(DATABASE_CREATE_TABLE_CHILDINFO);
		} catch (SQLException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}
		Log.d(TAG, "Child Table created.");
		return true;
	}
	
	public boolean addChild(Child child) throws InternalDBException {
		try{
			Log.d(TAG, child.toString());
			db.insert(DATABASE_TABLE_CHILD, null, getContentValues(child));
		} catch (SQLiteException e){
			Log.e(TAG, e.getMessage());
			return false; //TODO: throw exception?
		} catch (NullPointerException e) {
			Log.e(TAG, "Null Pointer!!");
			return false;
		}
		return true;
	}
	
	public ArrayList<Child> getChildList(String userId) throws InternalDBException, ObjectNotFoundException {
		//TODO:
		ArrayList<Child> result = new ArrayList<Child>();
		try{	
			String[] columns = { 
					CHILD_ID, 
					CHILD_PARENT_ID, 
					CHILD_NAME,
					CHILD_AGE,
					CHILD_GENDER,
					CHILD_INFO,
					CHILD_PIC_PATH
			};
			String[] SearchArg = { userId };
			
			Cursor cursor = db.query(DATABASE_TABLE_CHILD, columns, CHILD_PARENT_ID + "=?", SearchArg, null, null, null);			
			if(cursor.getCount() == 0){
				result = null;
				return result;
			}
			
			if (cursor != null ){
				cursor.moveToFirst();
			}
			
			do {
				Child child = new Child(); 
				child.setCid((getString(cursor, CHILD_ID)));
				child.setChildparentid((getString(cursor, CHILD_PARENT_ID)));
				child.setChildname(getString(cursor, CHILD_NAME));
				child.setChildage(getInt(cursor, CHILD_AGE));
				child.setChildgender(getInt(cursor, CHILD_GENDER));
				child.setChildinfo(getString(cursor, CHILD_INFO));
				child.setChildPicPath(getString(cursor, CHILD_PIC_PATH));
				result.add(child);
			} while(cursor.moveToNext());
			
		} catch (SQLiteException e){
			Log.e(TAG, e.getMessage());
			Log.d(TAG, "[User id: " + userId + "] detail: "+ e.toString());
			throw new InternalDBException("Error getting list of child.");
			
		} catch (NullPointerException e){
			Log.e(TAG, e.getMessage());
			Log.d(TAG, "User id: " + userId);
			throw new ObjectNotFoundException("This child is not exist.");
		}
		
		return result;
	}
	
	public Child getChildInfo(String cid) throws InternalDBException, ObjectNotFoundException {
		//TODO:
		Child child = new Child(); 
		try{	
			String[] columns = { 
					CHILD_ID, 
					CHILD_PARENT_ID, 
					CHILD_NAME,
					CHILD_AGE,
					CHILD_GENDER,
					CHILD_INFO,
					CHILD_PIC_PATH
			};
			String[] SearchArg = { cid };
			
			Cursor cursor = db.query(DATABASE_TABLE_CHILD, columns, CHILD_ID + "=?", SearchArg, null, null, null);			
	
			if (cursor != null){
				cursor.moveToFirst();
			}			
			
			if (cursor.getCount() > 0) {
				child.setCid(cid);
				child.setChildparentid((getString(cursor, CHILD_PARENT_ID)));
				child.setChildname(getString(cursor, CHILD_NAME));
				child.setChildage(getInt(cursor, CHILD_AGE));
				child.setChildgender(getInt(cursor, CHILD_GENDER));
				child.setChildinfo(getString(cursor, CHILD_INFO));
				child.setChildPicPath(getString(cursor, CHILD_PIC_PATH));
			} else {
				Log.d(TAG, "Child not found. Child id: " + cid);
				throw new ObjectNotFoundException("This child is not exist.");
			}
			
		} catch (SQLiteException e){
			Log.e(TAG, e.getMessage());
			Log.d(TAG, "[Child id: " + cid + "] detail: "+ e.toString());
			throw new InternalDBException("Could not get child information.");
			
		} catch (NullPointerException e){
			Log.e(TAG, e.getMessage());
			Log.d(TAG, "Child id: " + cid);
			throw new ObjectNotFoundException("This child is not exist.");
		}
		
		if(child.getCid() == null){
			Log.d(TAG, "Child not found. Child id: " + cid);
			throw new ObjectNotFoundException("This child is not exist.");
		} 
		
		return child;
	}
	
	public void updateChildInfo(Child child) throws InternalDBException, ObjectNotFoundException {
		try{	
			String[] args = {child.getCid()};
			int rows = db.update(
				DATABASE_TABLE_CHILD, 
				getContentValues(child), 
				CHILD_ID + "=?",
				args
			);
			
			if (rows < 1){
				Log.d(TAG, "Child data: " + child.toString());
				throw new ObjectNotFoundException("This child is not exist.");
			} else if (rows > 1){
				Log.w(TAG, "Updated more than one record.");
			}
			
		} catch (SQLiteException e){
			Log.e(TAG, e.getMessage());
			Log.d(TAG, "[Child id: " + child.getCid() + "] detail: "+ e.toString());
			throw new InternalDBException("Could not update child information.");
		}
	}
	
	public boolean deleteChild(String cid) throws InternalDBException, ObjectNotFoundException {
		String[] args = {cid};
		AchievementAdapter.deleteChildAchievementByChildId(db, cid);
		int count = db.delete(DATABASE_TABLE_CHILD, CHILD_ID + "=?", args);
		return count > 0;
	}
	
	protected static ContentValues getContentValues(Child child) {
		ContentValues contentValues = new ContentValues();
		contentValues.put(CHILD_ID, child.getCid());
		contentValues.put(CHILD_PARENT_ID, child.getChildparentid());
		contentValues.put(CHILD_NAME, child.getChildname());
		contentValues.put(CHILD_AGE, child.getChildage());
		contentValues.put(CHILD_GENDER, child.getChildgender());
		contentValues.put(CHILD_INFO, child.getChildinfo());
		contentValues.put(CHILD_PIC_PATH, child.getChildPicPath());
		return contentValues;
	}
	
}
